{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "d:\\AI\\Anaconda3\\lib\\site-packages\\sklearn\\cross_validation.py:41: DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. Also note that the interface of the new CV iterators are different from that of this module. This module will be removed in 0.20.\n",
      "  \"This module will be removed in 0.20.\", DeprecationWarning)\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "import sys\n",
    "import numpy as np  # 矩阵操作\n",
    "import pandas as pd # SQL数据处理\n",
    "import seaborn as sns\n",
    "import matplotlib.pyplot as plt   #画图\n",
    "from sklearn.metrics import r2_score  #评价回归预测模型的性能\n",
    "from sklearn.model_selection import train_test_split # 数据分割\n",
    "# 数据标准化\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "# 线性回归\n",
    "from sklearn.linear_model import LinearRegression\n",
    "# 线性模型，随机梯度下降优化模型参数\n",
    "from sklearn.linear_model import SGDRegressor\n",
    "#岭回归 --> L2正则\n",
    "from sklearn.linear_model import  RidgeCV\n",
    "# Lasso --> L1正则\n",
    "from sklearn.linear_model import LassoCV\n",
    "from sklearn.preprocessing import LabelEncoder\n",
    "from sklearn.preprocessing import OneHotEncoder\n",
    "\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.cross_validation import cross_val_score\n",
    "\n",
    "# 图形出现在Notebook里而不是新窗口\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 读取数据文件并总体概览\n",
    "data_path = 'G:\\\\study\\\\AI\\\\git\\\\machine_learning\\\\week2\\\\'\n",
    "data_filename = 'diabetes.csv'\n",
    "data_full_filename = data_path + data_filename\n",
    "data_save_filename = data_path + 'result_save.csv'\n",
    "\n",
    "if not os.path.exists(data_full_filename):\n",
    "    print('[-] file(%s) is not found!', data_full_filename)\n",
    "    sys.exit(-1)\n",
    "    \n",
    "data = pd.read_csv(data_full_filename)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 开始数据探索"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(768, 9)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Pregnancies</th>\n",
       "      <th>Glucose</th>\n",
       "      <th>BloodPressure</th>\n",
       "      <th>SkinThickness</th>\n",
       "      <th>Insulin</th>\n",
       "      <th>BMI</th>\n",
       "      <th>DiabetesPedigreeFunction</th>\n",
       "      <th>Age</th>\n",
       "      <th>Outcome</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>6</td>\n",
       "      <td>148</td>\n",
       "      <td>72</td>\n",
       "      <td>35</td>\n",
       "      <td>0</td>\n",
       "      <td>33.6</td>\n",
       "      <td>0.627</td>\n",
       "      <td>50</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>85</td>\n",
       "      <td>66</td>\n",
       "      <td>29</td>\n",
       "      <td>0</td>\n",
       "      <td>26.6</td>\n",
       "      <td>0.351</td>\n",
       "      <td>31</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>8</td>\n",
       "      <td>183</td>\n",
       "      <td>64</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>23.3</td>\n",
       "      <td>0.672</td>\n",
       "      <td>32</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1</td>\n",
       "      <td>89</td>\n",
       "      <td>66</td>\n",
       "      <td>23</td>\n",
       "      <td>94</td>\n",
       "      <td>28.1</td>\n",
       "      <td>0.167</td>\n",
       "      <td>21</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>137</td>\n",
       "      <td>40</td>\n",
       "      <td>35</td>\n",
       "      <td>168</td>\n",
       "      <td>43.1</td>\n",
       "      <td>2.288</td>\n",
       "      <td>33</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   Pregnancies  Glucose  BloodPressure  SkinThickness  Insulin   BMI  \\\n",
       "0            6      148             72             35        0  33.6   \n",
       "1            1       85             66             29        0  26.6   \n",
       "2            8      183             64              0        0  23.3   \n",
       "3            1       89             66             23       94  28.1   \n",
       "4            0      137             40             35      168  43.1   \n",
       "\n",
       "   DiabetesPedigreeFunction  Age  Outcome  \n",
       "0                     0.627   50        1  \n",
       "1                     0.351   31        0  \n",
       "2                     0.672   32        1  \n",
       "3                     0.167   21        0  \n",
       "4                     2.288   33        1  "
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Pregnancies</th>\n",
       "      <th>Glucose</th>\n",
       "      <th>BloodPressure</th>\n",
       "      <th>SkinThickness</th>\n",
       "      <th>Insulin</th>\n",
       "      <th>BMI</th>\n",
       "      <th>DiabetesPedigreeFunction</th>\n",
       "      <th>Age</th>\n",
       "      <th>Outcome</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>768.000000</td>\n",
       "      <td>768.000000</td>\n",
       "      <td>768.000000</td>\n",
       "      <td>768.000000</td>\n",
       "      <td>768.000000</td>\n",
       "      <td>768.000000</td>\n",
       "      <td>768.000000</td>\n",
       "      <td>768.000000</td>\n",
       "      <td>768.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>3.845052</td>\n",
       "      <td>120.894531</td>\n",
       "      <td>69.105469</td>\n",
       "      <td>20.536458</td>\n",
       "      <td>79.799479</td>\n",
       "      <td>31.992578</td>\n",
       "      <td>0.471876</td>\n",
       "      <td>33.240885</td>\n",
       "      <td>0.348958</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>3.369578</td>\n",
       "      <td>31.972618</td>\n",
       "      <td>19.355807</td>\n",
       "      <td>15.952218</td>\n",
       "      <td>115.244002</td>\n",
       "      <td>7.884160</td>\n",
       "      <td>0.331329</td>\n",
       "      <td>11.760232</td>\n",
       "      <td>0.476951</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.078000</td>\n",
       "      <td>21.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>1.000000</td>\n",
       "      <td>99.000000</td>\n",
       "      <td>62.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>27.300000</td>\n",
       "      <td>0.243750</td>\n",
       "      <td>24.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>3.000000</td>\n",
       "      <td>117.000000</td>\n",
       "      <td>72.000000</td>\n",
       "      <td>23.000000</td>\n",
       "      <td>30.500000</td>\n",
       "      <td>32.000000</td>\n",
       "      <td>0.372500</td>\n",
       "      <td>29.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>6.000000</td>\n",
       "      <td>140.250000</td>\n",
       "      <td>80.000000</td>\n",
       "      <td>32.000000</td>\n",
       "      <td>127.250000</td>\n",
       "      <td>36.600000</td>\n",
       "      <td>0.626250</td>\n",
       "      <td>41.000000</td>\n",
       "      <td>1.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>17.000000</td>\n",
       "      <td>199.000000</td>\n",
       "      <td>122.000000</td>\n",
       "      <td>99.000000</td>\n",
       "      <td>846.000000</td>\n",
       "      <td>67.100000</td>\n",
       "      <td>2.420000</td>\n",
       "      <td>81.000000</td>\n",
       "      <td>1.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       Pregnancies     Glucose  BloodPressure  SkinThickness     Insulin  \\\n",
       "count   768.000000  768.000000     768.000000     768.000000  768.000000   \n",
       "mean      3.845052  120.894531      69.105469      20.536458   79.799479   \n",
       "std       3.369578   31.972618      19.355807      15.952218  115.244002   \n",
       "min       0.000000    0.000000       0.000000       0.000000    0.000000   \n",
       "25%       1.000000   99.000000      62.000000       0.000000    0.000000   \n",
       "50%       3.000000  117.000000      72.000000      23.000000   30.500000   \n",
       "75%       6.000000  140.250000      80.000000      32.000000  127.250000   \n",
       "max      17.000000  199.000000     122.000000      99.000000  846.000000   \n",
       "\n",
       "              BMI  DiabetesPedigreeFunction         Age     Outcome  \n",
       "count  768.000000                768.000000  768.000000  768.000000  \n",
       "mean    31.992578                  0.471876   33.240885    0.348958  \n",
       "std      7.884160                  0.331329   11.760232    0.476951  \n",
       "min      0.000000                  0.078000   21.000000    0.000000  \n",
       "25%     27.300000                  0.243750   24.000000    0.000000  \n",
       "50%     32.000000                  0.372500   29.000000    0.000000  \n",
       "75%     36.600000                  0.626250   41.000000    1.000000  \n",
       "max     67.100000                  2.420000   81.000000    1.000000  "
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.describe()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 对一些参数为0的列，进行平均值填充\n",
    "fill_coloumns = ['Glucose', 'BMI', 'BloodPressure', 'SkinThickness']\n",
    "#data[fill_coloumns] = data[fill_coloumns].replace(0, np.NaN)\n",
    "for col in fill_coloumns:\n",
    "    mean_val = data[col].median()\n",
    "    data[col] = data[col].replace(0, np.NaN)\n",
    "    data[col] = data[col].fillna(mean_val)\n",
    "    \n",
    "#mean_val = data.median()\n",
    "#print(mean_val)\n",
    "#data = data.fillna(mean_val)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 768 entries, 0 to 767\n",
      "Data columns (total 9 columns):\n",
      "Pregnancies                 768 non-null int64\n",
      "Glucose                     768 non-null float64\n",
      "BloodPressure               768 non-null float64\n",
      "SkinThickness               768 non-null float64\n",
      "Insulin                     768 non-null int64\n",
      "BMI                         768 non-null float64\n",
      "DiabetesPedigreeFunction    768 non-null float64\n",
      "Age                         768 non-null int64\n",
      "Outcome                     768 non-null int64\n",
      "dtypes: float64(5), int64(4)\n",
      "memory usage: 54.1 KB\n"
     ]
    }
   ],
   "source": [
    "data.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 768 entries, 0 to 767\n",
      "Data columns (total 9 columns):\n",
      "Pregnancies                 768 non-null int64\n",
      "Glucose                     768 non-null float64\n",
      "BloodPressure               768 non-null float64\n",
      "SkinThickness               768 non-null float64\n",
      "Insulin                     768 non-null int64\n",
      "BMI                         768 non-null float64\n",
      "DiabetesPedigreeFunction    768 non-null float64\n",
      "Age                         768 non-null int64\n",
      "Outcome                     768 non-null int64\n",
      "dtypes: float64(5), int64(4)\n",
      "memory usage: 54.1 KB\n"
     ]
    }
   ],
   "source": [
    "data.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x222d2c67748>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 看一下样本分布是否均衡\n",
    "sns.countplot(data.Outcome)\n",
    "plt.xlabel('Outcome dist')\n",
    "\n",
    "# 等下可以在LogisticRegression回归中尝试使用如下的权重值进行测试\n",
    "class_weight_samples = {0:0.5, 1:1}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 从上面的数据分析来看，所有9列数据全部为数值，非空，这里可以不再处理。数值间差异有点大，可以考虑标准化和归一化"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 开始数据分析"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(614, 8)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 按要求选择20%的数据用作测试集\n",
    "y = data.Outcome\n",
    "X = data.drop(['Outcome'], axis = 1)\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 33)\n",
    "\n",
    "# 数据分割后X_train_rate = 614 / 768 = 0.79948\n",
    "X_train.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 数据标准化\n",
    "ss_X = StandardScaler()\n",
    "ss_y = StandardScaler()\n",
    "\n",
    "X_train = ss_X.fit_transform(X_train)\n",
    "X_test = ss_X.transform(X_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# LogisticRegression模型训练\n",
    "通过设置class_weight值来看下不同参数下模型的logless值，从结果看不设置class_weight反而还要好些。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "logloss of each fold is:  [0.44027726 0.51039314 0.45492141]\n",
      "cv logloss is:  0.468530600270294\n"
     ]
    }
   ],
   "source": [
    "lr = LogisticRegression()\n",
    "loss = cross_val_score(lr, X_train, y_train, cv = 3, scoring = 'neg_log_loss')\n",
    "print('logloss of each fold is: ', -loss)\n",
    "print('cv logloss is: ', -loss.mean())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "logloss of each fold is:  [0.47234853 0.54585084 0.49508977]\n",
      "cv logloss is:  0.5044297140762326\n"
     ]
    }
   ],
   "source": [
    "lr_class_weight_indicate = LogisticRegression(class_weight = class_weight_samples)\n",
    "loss_class_weight_indicate = cross_val_score(lr_class_weight_indicate, X_train, y_train, cv = 3, scoring = 'neg_log_loss')\n",
    "print('logloss of each fold is: ', -loss_class_weight_indicate)\n",
    "print('cv logloss is: ', -loss_class_weight_indicate.mean())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "logloss of each fold is:  [0.46599559 0.54129541 0.48849972]\n",
      "cv logloss is:  0.4985969060282602\n"
     ]
    }
   ],
   "source": [
    "lr_class_weight_indicate = LogisticRegression(class_weight = 'balanced')\n",
    "loss_class_weight_indicate = cross_val_score(lr_class_weight_indicate, X_train, y_train, cv = 3, scoring = 'neg_log_loss')\n",
    "print('logloss of each fold is: ', -loss_class_weight_indicate)\n",
    "print('cv logloss is: ', -loss_class_weight_indicate.mean())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 通过GridSearch来实现超参数调优\n",
    "从结果看，如果超参数也设置了class_weight可选，执行时可能会产生两种结果(best_score_ 和 best_params_ 如下，值可能随执行次数改变，这里是记录):\n",
    "1. 0.4898180403981575  {'C': 1, 'class_weight': None, 'penalty': 'l1'}\n",
    "2. 0.4857084977902917  {'C': 0.1, 'class_weight': None, 'penalty': 'l2'}\n",
    "\n",
    "如果不设置class_weight进行超参数调优，则也会得到两种结果：\n",
    "1. 0.4901743667209677  {'C': 1, 'penalty': 'l1'}\n",
    "2. 0.49936300574368986 {'C': 0.1, 'penalty': 'l2'}\n",
    "\n",
    "但是从总体执行结果来看，参数调优的模型比完全使用默认值的模型性能要好"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "d:\\AI\\Anaconda3\\lib\\site-packages\\sklearn\\utils\\deprecation.py:122: FutureWarning: You are accessing a training score ('mean_train_score'), which will not be available by default any more in 0.21. If you need training scores, please set return_train_score=True\n",
      "  warnings.warn(*warn_args, **warn_kwargs)\n",
      "d:\\AI\\Anaconda3\\lib\\site-packages\\sklearn\\utils\\deprecation.py:122: FutureWarning: You are accessing a training score ('split0_train_score'), which will not be available by default any more in 0.21. If you need training scores, please set return_train_score=True\n",
      "  warnings.warn(*warn_args, **warn_kwargs)\n",
      "d:\\AI\\Anaconda3\\lib\\site-packages\\sklearn\\utils\\deprecation.py:122: FutureWarning: You are accessing a training score ('split1_train_score'), which will not be available by default any more in 0.21. If you need training scores, please set return_train_score=True\n",
      "  warnings.warn(*warn_args, **warn_kwargs)\n",
      "d:\\AI\\Anaconda3\\lib\\site-packages\\sklearn\\utils\\deprecation.py:122: FutureWarning: You are accessing a training score ('split2_train_score'), which will not be available by default any more in 0.21. If you need training scores, please set return_train_score=True\n",
      "  warnings.warn(*warn_args, **warn_kwargs)\n",
      "d:\\AI\\Anaconda3\\lib\\site-packages\\sklearn\\utils\\deprecation.py:122: FutureWarning: You are accessing a training score ('std_train_score'), which will not be available by default any more in 0.21. If you need training scores, please set return_train_score=True\n",
      "  warnings.warn(*warn_args, **warn_kwargs)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'mean_fit_time': array([0.00166392, 0.00066781, 0.00100215, 0.00066876, 0.00100025,\n",
       "        0.00150569, 0.00150021, 0.00100311, 0.        , 0.00033387,\n",
       "        0.00076445, 0.        , 0.00334485, 0.        ]),\n",
       " 'mean_score_time': array([0.00100398, 0.00100239, 0.00200542, 0.00100358, 0.00100334,\n",
       "        0.00100652, 0.0008351 , 0.00033418, 0.00033426, 0.00333452,\n",
       "        0.00066829, 0.        , 0.        , 0.        ]),\n",
       " 'mean_test_score': array([-0.69314718, -0.64326166, -0.69134331, -0.5258194 , -0.47525774,\n",
       "        -0.46963775, -0.46852771, -0.46855277, -0.46935546, -0.46937991,\n",
       "        -0.46947421, -0.469483  , -0.46949224, -0.46949354]),\n",
       " 'mean_train_score': array([-0.69314718, -0.64271823, -0.6910102 , -0.52240575, -0.46722512,\n",
       "        -0.45882841, -0.45288879, -0.45266832, -0.45254495, -0.45254272,\n",
       "        -0.45254136, -0.45254132, -0.45254131, -0.45254131]),\n",
       " 'param_C': masked_array(data=[0.001, 0.001, 0.01, 0.01, 0.1, 0.1, 1, 1, 10, 10, 100,\n",
       "                    100, 1000, 1000],\n",
       "              mask=[False, False, False, False, False, False, False, False,\n",
       "                    False, False, False, False, False, False],\n",
       "        fill_value='?',\n",
       "             dtype=object),\n",
       " 'param_penalty': masked_array(data=['l1', 'l2', 'l1', 'l2', 'l1', 'l2', 'l1', 'l2', 'l1',\n",
       "                    'l2', 'l1', 'l2', 'l1', 'l2'],\n",
       "              mask=[False, False, False, False, False, False, False, False,\n",
       "                    False, False, False, False, False, False],\n",
       "        fill_value='?',\n",
       "             dtype=object),\n",
       " 'params': [{'C': 0.001, 'penalty': 'l1'},\n",
       "  {'C': 0.001, 'penalty': 'l2'},\n",
       "  {'C': 0.01, 'penalty': 'l1'},\n",
       "  {'C': 0.01, 'penalty': 'l2'},\n",
       "  {'C': 0.1, 'penalty': 'l1'},\n",
       "  {'C': 0.1, 'penalty': 'l2'},\n",
       "  {'C': 1, 'penalty': 'l1'},\n",
       "  {'C': 1, 'penalty': 'l2'},\n",
       "  {'C': 10, 'penalty': 'l1'},\n",
       "  {'C': 10, 'penalty': 'l2'},\n",
       "  {'C': 100, 'penalty': 'l1'},\n",
       "  {'C': 100, 'penalty': 'l2'},\n",
       "  {'C': 1000, 'penalty': 'l1'},\n",
       "  {'C': 1000, 'penalty': 'l2'}],\n",
       " 'rank_test_score': array([14, 12, 13, 11, 10,  9,  1,  2,  3,  4,  5,  6,  7,  8]),\n",
       " 'split0_test_score': array([-0.69314718, -0.64273305, -0.69314718, -0.51968552, -0.46333721,\n",
       "        -0.45021871, -0.44191221, -0.44027726, -0.43955105, -0.43940553,\n",
       "        -0.43933548, -0.43932144, -0.43931863, -0.43931306]),\n",
       " 'split0_train_score': array([-0.69314718, -0.6437735 , -0.69314718, -0.5285328 , -0.4774027 ,\n",
       "        -0.47036113, -0.46564677, -0.46544971, -0.46536217, -0.46536018,\n",
       "        -0.46535923, -0.46535921, -0.4653592 , -0.46535919]),\n",
       " 'split1_test_score': array([-0.69314718, -0.64332429, -0.68774437, -0.53025096, -0.49499104,\n",
       "        -0.49550129, -0.50858616, -0.51039314, -0.51403178, -0.51423585,\n",
       "        -0.51463546, -0.5146703 , -0.5147068 , -0.5147143 ]),\n",
       " 'split1_train_score': array([-0.69314718, -0.64233028, -0.68673624, -0.51546268, -0.45163641,\n",
       "        -0.4414391 , -0.43336351, -0.4331166 , -0.43293284, -0.43293035,\n",
       "        -0.43292829, -0.43292824, -0.43292822, -0.43292822]),\n",
       " 'split2_test_score': array([-0.69314718, -0.64372994, -0.69314718, -0.52753007, -0.46740669,\n",
       "        -0.46316165, -0.45501885, -0.45492141, -0.45441065, -0.45442541,\n",
       "        -0.45437805, -0.45438363, -0.45437757, -0.45437953]),\n",
       " 'split2_train_score': array([-0.69314718, -0.6420509 , -0.69314718, -0.52322176, -0.47263626,\n",
       "        -0.46468501, -0.45965607, -0.45943865, -0.45933985, -0.45933764,\n",
       "        -0.45933655, -0.45933652, -0.45933651, -0.45933651]),\n",
       " 'std_fit_time': array([4.73731217e-04, 4.72213542e-04, 2.97360213e-07, 4.72887650e-04,\n",
       "        2.18803086e-06, 7.11551301e-04, 1.07739667e-03, 6.25769923e-07,\n",
       "        0.00000000e+00, 4.72157095e-04, 5.48317338e-04, 0.00000000e+00,\n",
       "        4.73033749e-03, 0.00000000e+00]),\n",
       " 'std_score_time': array([1.66324373e-06, 1.12391596e-07, 1.41759520e-03, 9.79807218e-07,\n",
       "        4.05233662e-07, 7.14361011e-04, 2.36305756e-04, 4.72606661e-04,\n",
       "        4.72719053e-04, 4.71572659e-03, 4.72558896e-04, 0.00000000e+00,\n",
       "        0.00000000e+00, 0.00000000e+00]),\n",
       " 'std_test_score': array([9.07231190e-17, 4.09221135e-04, 2.54794546e-03, 4.48231254e-03,\n",
       "        1.40689479e-02, 1.90571831e-02, 2.88601575e-02, 3.02185544e-02,\n",
       "        3.22055556e-02, 3.23427863e-02, 3.25567928e-02, 3.25764091e-02,\n",
       "        3.25951121e-02, 3.26000092e-02]),\n",
       " 'std_train_score': array([9.06493304e-17, 7.54859025e-04, 3.02214543e-03, 5.36696124e-03,\n",
       "        1.11933222e-02, 1.25125443e-02, 1.40213969e-02, 1.40412638e-02,\n",
       "        1.40841097e-02, 1.40843118e-02, 1.40848004e-02, 1.40848114e-02,\n",
       "        1.40848166e-02, 1.40848163e-02])}"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.model_selection import GridSearchCV\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "\n",
    "penalty_v = ['l1', 'l2']\n",
    "C_v = [0.001, 0.01, 0.1, 1, 10, 100, 1000]\n",
    "class_weight_v = [{0:0.5, 1:1}, 'balanced', None]\n",
    "#tuned_params = dict(penalty = penalty_v, C = C_v, class_weight = class_weight_v)\n",
    "tuned_params = dict(penalty = penalty_v, C = C_v)\n",
    "lr_penalty = LogisticRegression()\n",
    "grid = GridSearchCV(lr_penalty, tuned_params, cv = 3, scoring = 'neg_log_loss')\n",
    "grid.fit(X_train, y_train)\n",
    "grid.cv_results_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.46852770541346905\n",
      "{'C': 1, 'penalty': 'l1'}\n"
     ]
    }
   ],
   "source": [
    "print(-grid.best_score_)\n",
    "print(grid.best_params_)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 通过细化超参数C的值，以此得到当前LogisticRegression最优的超参数解"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.4683416954624108\n",
      "LogisticRegression模型的最优解为:  {'C': 0.6, 'penalty': 'l1'}\n"
     ]
    }
   ],
   "source": [
    "C_best_now = grid.best_params_['C']\n",
    "penalty_best = [grid.best_params_['penalty']]\n",
    "C_v_again = [C_best_now * .6,  C_best_now * .65,  C_best_now * .7,   C_best_now * .75, C_best_now * .8, \n",
    "             C_best_now * .85, C_best_now * .9,   C_best_now * .95,  C_best_now,       C_best_now * 1.05, \n",
    "             C_best_now * 1.1, C_best_now * 1.15, C_best_now * 1.25, C_best_now * 1.3, C_best_now * 1.35, \n",
    "             C_best_now * 1.4]\n",
    "tuned_params = dict(penalty = penalty_best, C = C_v_again)\n",
    "lr_penalty = LogisticRegression()\n",
    "grid = GridSearchCV(lr_penalty, tuned_params, cv = 3, scoring = 'neg_log_loss')\n",
    "grid.fit(X_train, y_train)\n",
    "print(-grid.best_score_)\n",
    "print('LogisticRegression模型的最优解为: ', grid.best_params_)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 保存LogisticRegression模型的最优解到pandas，用于后续保存到文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "dict_save = {'Logistic_C_best':grid.best_params_['C'], 'Logistic_penalty_best':penalty_best};"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 线性SVM模型训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "LinearSVC C(0.000010) accuracy: 0.720779\n",
      "LinearSVC C(0.000464) accuracy: 0.714286\n",
      "LinearSVC C(0.021544) accuracy: 0.733766\n",
      "LinearSVC C(1.000000) accuracy: 0.727273\n",
      "LinearSVC C(46.415888) accuracy: 0.766234\n",
      "LinearSVC C(2154.434690) accuracy: 0.603896\n",
      "LinearSVC C(100000.000000) accuracy: 0.688312\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "No handles with labels found to put in legend.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<function matplotlib.pyplot.show>"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x222d2cbaf60>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from sklearn.svm import LinearSVC\n",
    "C_linearsvm_v = np.logspace(-5, 5, 7)\n",
    "\n",
    "accuracy_v = []\n",
    "for v in C_linearsvm_v:\n",
    "    svc = LinearSVC(C = v)\n",
    "    svc.fit(X_train, y_train)\n",
    "    y_predict = svc.predict(X_test)\n",
    "    accuracy = svc.score(X_test, y_test)\n",
    "    #print(\"accuracy: {}\".format(accuracy))\n",
    "    print(\"LinearSVC C(%f) accuracy: %lf\" % (v, accuracy))\n",
    "    accuracy_v.append(accuracy)\n",
    "    \n",
    "x_axis = np.log10(C_linearsvm_v)\n",
    "plt.plot(x_axis, np.array(accuracy_v), 'b-')\n",
    "\n",
    "plt.legend()\n",
    "plt.xlabel('log(C)')\n",
    "plt.ylabel('accuracy')\n",
    "#plt.savefig('linearsvm.png')\n",
    "\n",
    "plt.show"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 线性svm和logistic相比，准确性提高较多，由于没有使用GridSearchCV进行交叉验证，而是对数据分割来测试，所以性能不会比logistic更慢"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "线性SVM最佳的正则参数为:  0.7662337662337663\n"
     ]
    }
   ],
   "source": [
    "print('线性SVM最佳的正则参数为: ', max(accuracy_v))\n",
    "dict_save['LinearSVC_C'] = max(accuracy_v)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "#C_linearsvm_v = np.logspace(-5, 5, 7)\n",
    "#tuned_params = dict(C = C_linearsvm_v)\n",
    "#svc = LinearSVC()\n",
    "#grid_svc = GridSearchCV(svc, tuned_params, cv = 3, scoring = 'neg_log_loss')\n",
    "#grid_svc.fit(X_train, y_train)\n",
    "#print(-grid_svc.best_score_)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# RBF核的SVM模型训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.svm import SVC\n",
    "def fit_grid_point_RBF(C_v, gamma_v, X_train, y_train, X_test, y_test):\n",
    "    svc_rbf = SVC(C = C_v, kernel = 'rbf', gamma = gamma_v)\n",
    "    svc_rbf.fit(X_train, y_train)\n",
    "    accuracy = svc_rbf.score(X_test, y_test)\n",
    "    #print(\"accuracy: {}\".format(accuracy))\n",
    "    print(\"RBF-SVM C(%f) accuracy: %f, gamma: %f\" % (v, accuracy, gamma_v))\n",
    "    return accuracy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "RBF-SVM C(100000.000000) accuracy: 0.642857, gamma: 0.010000\n",
      "RBF-SVM C(100000.000000) accuracy: 0.642857, gamma: 0.215443\n",
      "RBF-SVM C(100000.000000) accuracy: 0.642857, gamma: 4.641589\n",
      "RBF-SVM C(100000.000000) accuracy: 0.642857, gamma: 100.000000\n",
      "RBF-SVM C(100000.000000) accuracy: 0.714286, gamma: 0.010000\n",
      "RBF-SVM C(100000.000000) accuracy: 0.720779, gamma: 0.215443\n",
      "RBF-SVM C(100000.000000) accuracy: 0.642857, gamma: 4.641589\n",
      "RBF-SVM C(100000.000000) accuracy: 0.642857, gamma: 100.000000\n",
      "RBF-SVM C(100000.000000) accuracy: 0.727273, gamma: 0.010000\n",
      "RBF-SVM C(100000.000000) accuracy: 0.707792, gamma: 0.215443\n",
      "RBF-SVM C(100000.000000) accuracy: 0.629870, gamma: 4.641589\n",
      "RBF-SVM C(100000.000000) accuracy: 0.642857, gamma: 100.000000\n",
      "RBF-SVM C(100000.000000) accuracy: 0.740260, gamma: 0.010000\n",
      "RBF-SVM C(100000.000000) accuracy: 0.642857, gamma: 0.215443\n",
      "RBF-SVM C(100000.000000) accuracy: 0.629870, gamma: 4.641589\n",
      "RBF-SVM C(100000.000000) accuracy: 0.642857, gamma: 100.000000\n",
      "\n",
      "best_C: 100.000000, best_gamma: 0.010000, best_accuracy: 0.740260\n"
     ]
    }
   ],
   "source": [
    "# 设置参数先试试，从结果看和线性svm差不多，较大的值也在边界附近，后续再调小参数试试\n",
    "C_rbfsvm_v = np.logspace(-2, 2, 4)\n",
    "gamma_rbfsvm_v = np.logspace(-2, 2, 4)\n",
    "\n",
    "accuracy_v = []\n",
    "best_C = 0\n",
    "best_gamma = 0\n",
    "best_accuracy = 0\n",
    "for i, oneC in enumerate(C_rbfsvm_v):\n",
    "  for j, gamma in enumerate(gamma_rbfsvm_v):\n",
    "    rst = fit_grid_point_RBF(oneC, gamma, X_train, y_train, X_test, y_test)\n",
    "    if rst > best_accuracy:\n",
    "        best_C = oneC\n",
    "        best_gamma = gamma\n",
    "        best_accuracy = rst\n",
    "        \n",
    "print('\\nbest_C: %f, best_gamma: %f, best_accuracy: %f' % (best_C, best_gamma, best_accuracy))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "RBF-SVM C(100000.000000) accuracy: 0.642857, gamma: 0.000001\n",
      "RBF-SVM C(100000.000000) accuracy: 0.642857, gamma: 0.000464\n",
      "RBF-SVM C(100000.000000) accuracy: 0.675325, gamma: 0.215443\n",
      "RBF-SVM C(100000.000000) accuracy: 0.642857, gamma: 100.000000\n",
      "RBF-SVM C(100000.000000) accuracy: 0.642857, gamma: 0.000001\n",
      "RBF-SVM C(100000.000000) accuracy: 0.642857, gamma: 0.000464\n",
      "RBF-SVM C(100000.000000) accuracy: 0.753247, gamma: 0.215443\n",
      "RBF-SVM C(100000.000000) accuracy: 0.642857, gamma: 100.000000\n",
      "RBF-SVM C(100000.000000) accuracy: 0.642857, gamma: 0.000001\n",
      "RBF-SVM C(100000.000000) accuracy: 0.733766, gamma: 0.000464\n",
      "RBF-SVM C(100000.000000) accuracy: 0.720779, gamma: 0.215443\n",
      "RBF-SVM C(100000.000000) accuracy: 0.642857, gamma: 100.000000\n",
      "RBF-SVM C(100000.000000) accuracy: 0.642857, gamma: 0.000001\n",
      "RBF-SVM C(100000.000000) accuracy: 0.746753, gamma: 0.000464\n",
      "RBF-SVM C(100000.000000) accuracy: 0.642857, gamma: 0.215443\n",
      "RBF-SVM C(100000.000000) accuracy: 0.642857, gamma: 100.000000\n",
      "\n",
      "best_C: 1.000000, best_gamma: 0.215443, best_accuracy: 0.753247\n"
     ]
    }
   ],
   "source": [
    "# 和线性svm差不多，把参数再调小试试，从结果看，调小参数后结果 >= 不调优参数的结果，但从总体结果看，这个数据上线性svm性能不错\n",
    "C_rbfsvm_v = np.logspace(-1, 2, 4)\n",
    "gamma_rbfsvm_v = np.logspace(-6, --2, 4)\n",
    "\n",
    "accuracy_v = []\n",
    "best_C = 0\n",
    "best_gamma = 0\n",
    "best_accuracy = 0\n",
    "for i, oneC in enumerate(C_rbfsvm_v):\n",
    "  for j, gamma in enumerate(gamma_rbfsvm_v):\n",
    "    rst = fit_grid_point_RBF(oneC, gamma, X_train, y_train, X_test, y_test)\n",
    "    accuracy_v.append(rst)\n",
    "    if rst > best_accuracy:\n",
    "        best_C = oneC\n",
    "        best_gamma = gamma\n",
    "        best_accuracy = rst\n",
    "        \n",
    "print('\\nbest_C: %f, best_gamma: %f, best_accuracy: %f' % (best_C, best_gamma, best_accuracy))\n",
    "dict_save['BPF_SVM_best_C'] = best_C\n",
    "dict_save['BPF_SVM_best_gamma'] = best_gamma\n",
    "dict_save['BPF_SVM_best_accuracy'] = best_accuracy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<function matplotlib.pyplot.show>"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x222d4deaeb8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "accuracy_s1 = np.array(accuracy_v).reshape(len(C_rbfsvm_v), len(gamma_rbfsvm_v))\n",
    "x_axis = np.log10(C_rbfsvm_v)\n",
    "for j, gamma in enumerate(gamma_rbfsvm_v):\n",
    "    plt.plot(x_axis, np.array(accuracy_s1[:,j]), label = 'Test log-gamma-' + str(round(gamma, 5)))\n",
    "\n",
    "plt.legend()\n",
    "plt.xlabel('log(C)')\n",
    "plt.ylabel('accuracy')\n",
    "#plt.savefig('RBF_svm.png')\n",
    "\n",
    "plt.show"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 保存三个模型参数调优结果到文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.DataFrame(dict_save)\n",
    "df.to_csv(data_save_filename)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
